package com.wisnews.config.aspectjLog;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.wisnews.pojo.sys.entity.VisitLog;
import com.wisnews.service.sys.IVisitLogService;
import com.wisnews.util.DateUtil;
import eu.bitwalker.useragentutils.UserAgent;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Objects;

/**
 * @Description：aop切面日志
 * @Author: yuyd
 * @Email: yyd8358@foxmail.com
 * @Date: 2021/2/8 10:03
 * @Version 1.0
 */
@Component
@Slf4j
@Aspect
public class AopVisitLog {
    
    @Autowired
    private IVisitLogService iVisitLogService;

    /**
     * @description: 定义qierudian
     * @param:
     * @return:
     * @author yuyd
     * @date: 2021/3/31 17:39
     */
      @Pointcut("execution(public * com.wisnews.controller..*.*(..))")
      public void controllerPointcut() {

      }

    /**
     * 环绕通知
     *
     * @param point 切入点
     * @return 原方法返回值
     * @throws Throwable 异常信息
     */
    @Around("controllerPointcut()")
    public Object aopMonitoring(ProceedingJoinPoint point) throws Throwable {
        log.info("======>进入日志切面类");
        //获取请求对象
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = Objects.requireNonNull(attributes).getRequest();

        //获取请求信息
        long startTime = System.currentTimeMillis();
        Object result = point.proceed();
        String header = request.getHeader("User-Agent");
        UserAgent userAgent = UserAgent.parseUserAgentString(header);

        String visitControllerMethod = String.format("%s.%s", point.getSignature().getDeclaringTypeName(),
                point.getSignature().getName());

        VisitLog visitLog = new VisitLog()
                .setThreadId(Long.toString(Thread.currentThread().getId()))
                .setIpAddr(getIpAddr(request))
                .setUrl(request.getRequestURL().toString())
                .setVisitControllerMethod(visitControllerMethod)
                .setHttpMethod(request.getMethod())
                .setTimeCost(Long.toString(System.currentTimeMillis() - startTime))
                .setUserAgent(userAgent.toString())
                .setBrowser(userAgent.getBrowser().getName())
                .setOs(userAgent.getOperatingSystem().getName())
                .setCreateTime(DateUtil.getLocalDateTime());
        iVisitLogService.save(visitLog);
        return result;
    }


   /**
    * @description: 获取访问的ip地址
    * @param:
    * @return:
    * @author yuyd
    * @date: 2021/3/31 17:39
    */
    public static String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (StringUtils.isBlank(ip)  || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        String comma = ",";
        String localhost = "127.0.0.1";
        if (ip.contains(comma)) {
            ip = ip.split(",")[0];
        }
        if (localhost.equals(ip)) {
            // 获取本机真正的ip地址
            try {
                ip = InetAddress.getLocalHost().getHostAddress();
            } catch (UnknownHostException e) {
                log.error(e.getMessage(), e);
            }
        }
        return ip;
    }
}
